package com.apes.framework.plugin.fsm;

import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.plugin.soe.metadata.BusinessType;
import com.apes.framework.util.JpaUtil;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 功能：状态流
 *
 * @author xul
 * @create 2020-08-27 11:37
 */
@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = FsmFlow.CONST_TABLE_NAME)
public class FsmFlow extends Model {
    public static final String CONST_TABLE_NAME = "fsm_flow";

    @Id
    @Column(name = "id", length = 32)
    @ApesGenerator(code = CONST_TABLE_NAME, name = "状态流")
    @Comment("编码")
    private String id;

    @Column(name = "name", nullable = false, length = 60)
    @Comment("状态流名称")
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "business_type_id", referencedColumnName = "id", nullable = false)
    @Comment("业务单据")
    private BusinessType businessType;

    @Column(name = "business_dept", length = 120)
    @Comment("业务部门")
    private String businessDept;

    @Column(name = "condition", length = 128)
    @Comment("条件")
    private String condition;

    @Column(name = "valid", nullable = false, columnDefinition = "number(1,0) default 1")
    @Comment("是否有效")
    private boolean valid = true;

    @OneToMany(mappedBy = "fsmFlow", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<FsmEvent> fsmEvents = new ArrayList<>();

    public List<FsmEvent> getFsmEvents() {
        for (FsmEvent event : fsmEvents) {
            event.setFsmFlow(this);
        }
        return fsmEvents;
    }

//    @Transient
//    private String flowChart;
//
//    public String getFlowChart() {
//        StateMachine stateMachine = SpringManager.getBean(FsmManager.class).createStateMachine(this);
//        if (stateMachine == null) {
//            return null;
//        }
//        DotVisitor visitor = SquirrelProvider.getInstance().newInstance(ApesDotVisitor.class);
//        stateMachine.accept(visitor);
//        return visitor.toString();
//    }

    public List<FsmState> findAllFsmStateByFsmFlow() {
        FsmStateRepository repository = SpringManager.getBean(FsmStateRepository.class);
        List<FsmState> states = repository.findAllByFsmFlowOrderByParentDesc(this);
        return states.stream().map(state -> (FsmState) JpaUtil.getImplementation(state)).collect(Collectors.toList());
    }

    public FsmState findInitialState() {
        List<FsmState> fsmStates = findAllFsmStateByFsmFlow();
        long count = fsmStates.stream().filter(state -> state.isStarted()).count();
//        if (count == 0) {
//            throw new RuntimeException(String.format("状态流：%s 请定义一个初始状态！", id));
//        } else if (count > 1) {
//            throw new RuntimeException(String.format("状态流：%s 只允许定义一个初始状态！", id));
//        }
        return fsmStates.stream().filter(state -> state.isStarted()).findFirst().orElse(null);
    }

    public void verify() {

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FsmFlow fsmFlow = (FsmFlow) o;
        return Objects.equals(id, fsmFlow.id);
    }

}
